﻿using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Owin;
using OAuth2Demo.Models;
using Microsoft.Owin.Security.OAuth;
using OAuth2Demo.Oauth2;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using Microsoft.Owin.Security.Infrastructure;
using Microsoft.Owin.Security.Jwt;

namespace OAuth2Demo
{
    public partial class Startup
    {
        // For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context, user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

            var issuer = "http://localhost:59273/";//身份验证服务器
            //创建OAuth授权服务器
            app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
            {
                //生产环境设为false
                AllowInsecureHttp = true,//重要！！这里的设置包含整个流程通信环境是否启用ssl
                AuthorizeEndpointPath = new PathString("/oauth2/authorize"),//请求路径，客户端应用程序将通过该路径重定向用户代理以获取用户对颁发令牌的同意。 必须以前导斜杠开头，如“/Authorize”。授权终结点
                TokenEndpointPath = new PathString("/oauth2/token"),//获取token的路径,生成Token的终结点
                //请求获取token时，验证username, password
                Provider = new DemoOAuthAuthorizationServerProvider(),//验证客户端跳转地址和客户端验证
                
                AuthorizationCodeProvider = new AuthorizationCodeProvider(),//authorization_code 认证服务     token提供器，负责token的生成
                RefreshTokenProvider = new RefreshTokenProvider(),
                AccessTokenFormat = new MyJwtFormat(issuer)//"ark9EjVCHrPOUeXqtpGCC9sAdeNn7+g8Un7xSTg7MjE=")
            });

            //为Audience(Client)添加用于解析Token的JwtBearerAuthentication中间件
            app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions()
            {
                //AuthenticationMode = AuthenticationMode.Active,
                AllowedAudiences = new[] { "test1" },//用户名从数据库读取
                IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                {
                    new SymmetricKeyIssuerSecurityTokenProvider(issuer, "LHZ5bUlOR2dzW1Yzd1dkbHdFbXNQSVBHSEs9dTZQKTE=")//密钥在这里是写死了，也可以写到配置文件中，但是要加密，这里写解密后的密钥
                }
            });



            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
            {

            });
            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information about a user logging in with a third party login provider
            // Configure the sign in cookie
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,//AuthenticationType是用户登陆Authorization Server后的登陆凭证的标记名，简单理解为cookie的键名就行。为什么要先提醒下呢，因为这和OAuth/Authorize中检查用户当前是否已登陆有关系，有时候，这个值的默认设置可能是”ApplicationCookie”
                LoginPath = new PathString("/Account/Login"),//401错误时重定向到登录页面
                Provider = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.  
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),//过期时间
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });            
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

            // Enables the application to remember the second login verification factor such as phone or email.
            // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
            // This is similar to the RememberMe option when you log in.
            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

            // Uncomment the following lines to enable logging in with third party login providers
            //app.UseMicrosoftAccountAuthentication(
           //     clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //   consumerKey: "",
            //   consumerSecret: "");

            //app.UseFacebookAuthentication(
            //   appId: "",
            //   appSecret: "");

            //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
            //{
            //    ClientId = "",
            //    ClientSecret = ""
            //});
        }
    }
}